package com.liuxinlong.modules.system.service.impl;

import com.liuxinlong.common.AosException;
import com.liuxinlong.common.ExcelData;
import com.liuxinlong.common.ExcelImportCallBack;
import com.liuxinlong.common.ExcelImportService;
import com.liuxinlong.common.ImportResp;
import com.liuxinlong.common.RowError;
import com.liuxinlong.common.SnowFlake;
import com.liuxinlong.enums.ReturnCodes;
import com.liuxinlong.modules.dao.DepartmentDao;
import com.liuxinlong.modules.dao.UserDao;
import com.liuxinlong.modules.entity.UserDepartment;
import com.liuxinlong.modules.system.service.DepartmentService;
import com.liuxinlong.utils.ExcelUtils;
import com.liuxinlong.utils.ObjectUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户部门实现类
 *
 * @author liuxinlong@hotwater.com.cn
 * @version 1.0.0
 * @since 2021-12-28
 */
@Service
@Slf4j
public class DepartmentServiceImpl implements DepartmentService {
    @Autowired
    private DepartmentDao departmentDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private ExcelImportService excelImportService;

    @Override
    public List<Map<String, Object>> pageDepartmentInfo(Map<String, Object> queryParam) {
        List<UserDepartment> originList = departmentDao.pageDepartmentList(queryParam);
        List<Map<String, Object>> resultList = new ArrayList<>(originList.size());
        int sort = (int) queryParam.get("startNum") + 1;
        for (UserDepartment department : originList) {
            Map<String, Object> map = ObjectUtils.object2Map(department);
            map.put("sort", sort);
            resultList.add(map);
            sort++;
        }
        return resultList;
    }

    @Override
    public int countDepartment(Map<String, Object> queryParam) {
        return departmentDao.getDepartmentCount(queryParam);
    }

    @Override
    public void addDepartmentInfo(UserDepartment userDepartment) {
        userDepartment.setId(SnowFlake.nextIdStr());
        if (!ObjectUtils.isEmpty(departmentDao.getDepartmentByName(userDepartment.getName()))) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "已存在相同名称！");
        }
        departmentDao.insert(userDepartment);
    }

    @Override
    public void updateDepartmentInfo(UserDepartment userDepartment) {
        UserDepartment oldInfo = departmentDao.getDepartmentByName(userDepartment.getName());
        if (!ObjectUtils.isEmpty(oldInfo) && !StringUtils.equals(oldInfo.getId(), userDepartment.getId())) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "已存在相同名称！");
        }
        departmentDao.updateById(userDepartment);
    }

    @Override
    public void deleteDepartmentInfo(String id) {
        Map<String, Object> queryParam = new HashMap<>();
        queryParam.put("department", id);
        if (userDao.getUserCount(queryParam) > 0) {
            throw new AosException(ReturnCodes.HTTP_PARAM_ERROR, "部门存在活跃用户，不可删除！");
        }
        departmentDao.deleteById(id);
    }

    @Override
    public ImportResp batchAddDepartment(List<UserDepartment> dataList) {
        for (UserDepartment userDepartment : dataList) {
            userDepartment.setId(SnowFlake.nextIdStr());
            departmentDao.insert(userDepartment);
        }
        ImportResp resp = new ImportResp();
        resp.setRetCode(ReturnCodes.HTTP_SUCCESS.getRetCode());
        resp.setRetMessage("导入部门信息成功");
        return resp;
    }

    @Override
    public void exportDepartment(HttpServletResponse response) {
        ExcelData data = new ExcelData();
        data.setFileName("部门信息导出excel.xlsx");
        List<UserDepartment> groupList = departmentDao.getDepartmentList();
        String[] head = {"序号", "部门名称", "部门编码", "描述"};
        data.setHead(head);
        String[][] dataList = new String[groupList.size()][head.length];
        int index = 0;
        for (UserDepartment item : groupList) {
            dataList[index][0] = String.valueOf(index + 1);
            dataList[index][1] = item.getName();
            dataList[index][2] = item.getSn();
            dataList[index][3] = item.getRemark();
            index++;
        }
        data.setData(Arrays.asList(dataList));
        ExcelUtils.exportExcel(response, data);
    }

    @Override
    public ImportResp importDepartments(String fileName) {
        String filePath = fileName;
        return excelImportService.excelFile(filePath, 2, new ExcelImportCallBack() {
            @Override
            public Collection<RowError> checkRow(String[] record) {
                return checkRecordValid(record);
            }

            @Override
            public boolean persistRowToDb(String[] record) {
                UserDepartment UserDepartment = covertToBean(record);
                return false;
//				try {
//					UserDepartmentDao.addDetail(UserDepartment);
//					return true;
//				} catch (Exception e) {
//					return false;
//				}
            }


            @Override
            public ImportResp partFailure(ImportResp resp) {
                resp.setRetMessage("导入部门数据部分失败，总数=" + resp.getTotal() + ",失败总数=" + resp.getFailedTotal());
                return resp;
            }

            @Override
            public ImportResp allSuccess(ImportResp resp) {
                resp.setRetMessage("导入部门数据全部成功，总数=" + resp.getTotal());
                return resp;
            }

            @Override
            public List<Map> convertFailList(List<String[]> failRecords) {
                List<Map> list = new ArrayList<>();
                int sort = 1;
                for (String[] failRecord : failRecords) {
                    Map item = new HashMap<>();
                    item.put("sort", sort);
                    item.put("name", failRecord[0]);
                    item.put("sn", failRecord[1]);
                    item.put("remark", failRecord[2]);
                    list.add(item);
                    sort++;
                }
                return list;
            }

        });
    }

    /**
     * 转换数据为入库数据
     *
     * @param record 数据记录
     * @return 入库数据
     */
    private UserDepartment covertToBean(String[] record) {
        UserDepartment userDepartment = new UserDepartment();
        userDepartment.setName(record[0].trim());
        userDepartment.setSn(record[1].trim());
        userDepartment.setRemark(record.length > 2 ? record[2].trim() : "");
        return userDepartment;

    }

    /**
     * 校验参数合法性
     *
     * @param record 导入数据
     * @return 参数合法性
     */
    private Collection<RowError> checkRecordValid(String[] record) {
        List<RowError> rowErrors = new ArrayList<>();
        if (StringUtils.isEmpty(record[0].trim())) {
            addRowError("部门名称不能为空", rowErrors);
        } else {
            if (record[0].trim().length() > 50) {
                addRowError("部门名称长度不能超过20", rowErrors);
            }
        }
        if (StringUtils.isEmpty(record[1].trim())) {
            addRowError("部门编码不能为空", rowErrors);
        } else {
            if (record[1].trim().length() > 20) {
                addRowError("部门编码长度不能超过20", rowErrors);
            }
        }
        if (record.length > 2 && !StringUtils.isEmpty(record[2].trim())) {
            if (record[2].trim().length() > 200) {
                addRowError("描述长度不能超过200", rowErrors);
            }
        }

        return rowErrors;
    }

    /**
     * 添加错误行数据
     *
     * @param errorMessage 错误信息
     * @param rowErrors    错误行数据
     */
    private void addRowError(String errorMessage, List<RowError> rowErrors) {
        RowError rowError = new RowError(errorMessage);
        rowErrors.add(rowError);
    }

}
